<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Highscore - The Boost C++ Libraries - Smart Pointers</title>
<link rel="stylesheet" href="css/highscore.css" type="text/css">
<link rev="made" href="mailto:boris@highscore.de">
<link rel="home" href="frontpage.html" title="The Boost C++ Libraries">
<link rel="up" href="frontpage.html" title="The Boost C++ Libraries">
<link rel="prev" href="introduction.html" title="Chapter 1: Introduction">
<link rel="next" href="functionobjects.html" title="Chapter 3: Function Objects">
<link rel="chapter" href="introduction.html" title="Chapter 1: Introduction">
<link rel="chapter" href="smartpointers.html" title="Chapter 2: Smart Pointers">
<link rel="chapter" href="functionobjects.html" title="Chapter 3: Function Objects">
<link rel="chapter" href="eventhandling.html" title="Chapter 4: Event Handling">
<link rel="chapter" href="stringhandling.html" title="Chapter 5: String Handling">
<link rel="chapter" href="multithreading.html" title="Chapter 6: Multithreading">
<link rel="chapter" href="asio.html" title="Chapter 7: Asynchronous Input and Output">
<link rel="chapter" href="interprocesscommunication.html" title="Chapter 8: Interprocess Communication">
<link rel="chapter" href="filesystem.html" title="Chapter 9: Filesystem">
<link rel="chapter" href="datetime.html" title="Chapter 10: Date and Time">
<link rel="chapter" href="serialization.html" title="Chapter 11: Serialization">
<link rel="chapter" href="parser.html" title="Chapter 12: Parser">
<link rel="chapter" href="containers.html" title="Chapter 13: Containers">
<link rel="chapter" href="datastructures.html" title="Chapter 14: Data Structures">
<link rel="chapter" href="errorhandling.html" title="Chapter 15: Error Handling">
<link rel="chapter" href="castoperators.html" title="Chapter 16: Cast Operators">
<link rel="section" href="smartpointers.html#smartpointers_general" title="2.1 General">
<link rel="section" href="smartpointers.html#smartpointers_raii" title="2.2 RAII">
<link rel="section" href="smartpointers.html#smartpointers_scoped_pointer" title="2.3 Scoped Pointer">
<link rel="section" href="smartpointers.html#smartpointers_scoped_array" title="2.4 Scoped Array">
<link rel="section" href="smartpointers.html#smartpointers_shared_pointer" title="2.5 Shared Pointer">
<link rel="section" href="smartpointers.html#smartpointers_shared_array" title="2.6 Shared Array">
<link rel="section" href="smartpointers.html#smartpointers_weak_pointer" title="2.7 Weak Pointer">
<link rel="section" href="smartpointers.html#smartpointers_intrusive_pointer" title="2.8 Intrusive Pointer">
<link rel="section" href="smartpointers.html#smartpointers_pointer_container" title="2.9 Pointer Container">
<link rel="section" href="smartpointers.html#smartpointers_exercises" title="2.10 Exercises">
<meta http-equiv="pics-label" content='(pics-1.1 "http://www.icra.org/ratingsv02.html" l gen true for "http://www.highscore.de" r (nz 1 vz 1 lz 1 oz 1 cz 1) gen true for "http://highscore.de" r (nz 1 vz 1 lz 1 oz 1 cz 1))'>
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<link href="http://www.highscore.de/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon">
<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script><script type="text/javascript" src="js/jquery.event.drag-1.5.min.js"></script><script type="text/javascript" src="js/highscore.js"></script>
</head>
<body>
<div lang="en" class="docbook chapter" title="Chapter 2: Smart Pointers">
<p class="title">The Boost C++ Libraries</p>
<script type="text/javascript">
          var titlepage = "Front page";
        
      var titles = new Array(titlepage,
      
        "Chapter 1: Introduction",
      
        "Chapter 2: Smart Pointers",
      
        "Chapter 3: Function Objects",
      
        "Chapter 4: Event Handling",
      
        "Chapter 5: String Handling",
      
        "Chapter 6: Multithreading",
      
        "Chapter 7: Asynchronous Input and Output",
      
        "Chapter 8: Interprocess Communication",
      
        "Chapter 9: Filesystem",
      
        "Chapter 10: Date and Time",
      
        "Chapter 11: Serialization",
      
        "Chapter 12: Parser",
      
        "Chapter 13: Containers",
      
        "Chapter 14: Data Structures",
      
        "Chapter 15: Error Handling",
      
        "Chapter 16: Cast Operators",
      
      "");

      
          var titlehtml = "frontpage.html";
        
      var filenames = new Array(titlehtml,
      
        "introduction.html",
      
        "smartpointers.html",
      
        "functionobjects.html",
      
        "eventhandling.html",
      
        "stringhandling.html",
      
        "multithreading.html",
      
        "asio.html",
      
        "interprocesscommunication.html",
      
        "filesystem.html",
      
        "datetime.html",
      
        "serialization.html",
      
        "parser.html",
      
        "containers.html",
      
        "datastructures.html",
      
        "errorhandling.html",
      
        "castoperators.html",
      
      "");

      
      document.open();
      document.write('<form action="" class="toc">');
      document.write('<select size="1" onchange="location.href=options[selectedIndex].value">');
      for (var i = 0; i < titles.length && i < filenames.length; ++i) {
        if (titles[i] != "" && filenames[i] != "") {
          document.write('<option');
          document.write(' value="' + filenames[i] + '"');
          var expr = new RegExp('[/\]' + filenames[i] + '$');
          if (expr.test(location.href)) {
            document.write(' selected="selected"');
          }
          document.write('>' + titles[i] + '<\/option>');
        }
      }
      document.write('<\/select>');
      document.write('<\/form>');
      document.close();
      
    </script><noscript><p class="toc"><a href="toc.html">Table of Contents</a></p></noscript>
<hr class="hrhead">
<h1 class="title">
<a name="smartpointers"></a><small>Chapter 2:</small> Smart Pointers</h1>
<hr>
<div class="toc">
<h3>Table of Contents</h3>
<ul>
<li><span class="sect1"><a href="smartpointers.html#smartpointers_general">2.1 General</a></span></li>
<li><span class="sect1"><a href="smartpointers.html#smartpointers_raii">2.2 RAII</a></span></li>
<li><span class="sect1"><a href="smartpointers.html#smartpointers_scoped_pointer">2.3 Scoped Pointer</a></span></li>
<li><span class="sect1"><a href="smartpointers.html#smartpointers_scoped_array">2.4 Scoped Array</a></span></li>
<li><span class="sect1"><a href="smartpointers.html#smartpointers_shared_pointer">2.5 Shared Pointer</a></span></li>
<li><span class="sect1"><a href="smartpointers.html#smartpointers_shared_array">2.6 Shared Array</a></span></li>
<li><span class="sect1"><a href="smartpointers.html#smartpointers_weak_pointer">2.7 Weak Pointer</a></span></li>
<li><span class="sect1"><a href="smartpointers.html#smartpointers_intrusive_pointer">2.8 Intrusive Pointer</a></span></li>
<li><span class="sect1"><a href="smartpointers.html#smartpointers_pointer_container">2.9 Pointer Container</a></span></li>
<li><span class="sect1"><a href="smartpointers.html#smartpointers_exercises">2.10 Exercises</a></span></li>
</ul>
</div>
<p class="license"><a href="http://creativecommons.org/licenses/by-nc-nd/3.0/" rel="license" target="_top"><img src="img/88x31_cc_logo.gif" alt="" width="88" height="31"></a> This book is licensed under a <a href="http://creativecommons.org/licenses/by-nc-nd/3.0/" rel="license" target="_top">Creative Commons License</a>.</p>
<hr>
<h2 class="title">
<a name="smartpointers_general"></a>2.1 General</h2>
<div class="sect1">
<p>The first version of the C++ standard adapted in 1998 only provides one smart pointer: <code class="classname">std::auto_ptr</code>. In principle, it behaves like a regular pointer: It provides access to a dynamically allocated object by storing its address. However, <code class="classname">std::auto_ptr</code> is considered intelligent and smart since it automatically releases the contained object during destruction by calling the <code class="code">delete</code> operator. This certainly requires that it is provided with the address of the object - returned by the <code class="code">new</code> operator - at initialization. Since the <code class="code">delete</code> operator is called within the destructor of <code class="classname">std::auto_ptr</code>, the associated memory for the contained object is guaranteed to be released. This is one advantage of smart pointers.</p>
<p>This becomes even more important in conjunction with exceptions: Without smart pointers such as <code class="classname">std::auto_ptr</code>, every function allocating dynamic memory would be required to catch every possible exception in order to release the memory prior to passing on the exception to its calling function. The Boost C++ Library <a class="link" href="http://www.boost.org/libs/smart_ptr/">Smart Pointers</a> provides many additional smart pointers that can be used in all kind of situations.</p>
</div>
<hr>
<h2 class="title">
<a name="smartpointers_raii"></a>2.2 RAII</h2>
<div class="sect1">
<p>The principle of smart pointers is based on a common idiom named RAII: Resource acquisition is initialization. Smart pointers are only one example for this idiom - certainly a very prominent one. Smart pointers are used to ensure that dynamically allocated memory is released properly under all circumstances, freeing the developer from the burden of managing this on her own. This includes scenarios in which execution of a function is interrupted by an exception and the instruction to release the memory is skipped. This guarantee is accomplished by initializing a smart pointer with the address of a dynamically allocated object which in turn is used to release the memory during destruction. Since the destructor is always executed the contained memory is therefore always released.</p>
<p>RAII is applied whenever a second instruction is mandatory in order to release a resource previously allocated by another instruction. Since many C++ applications require dynamically managed memory, smart pointers are an important RAII class. RAII itself can be applied in many other scenarios though.</p>
<pre class="programlisting">#include &lt;windows.h&gt; 

class windows_handle 
{ 
  public: 
    windows_handle(HANDLE h) 
      : handle_(h) 
    { 
    } 

    ~windows_handle() 
    { 
      CloseHandle(handle_); 
    } 

    HANDLE handle() const 
    { 
      return handle_; 
    } 

  private: 
    HANDLE handle_; 
}; 

int main() 
{ 
  windows_handle h(OpenProcess(PROCESS_SET_INFORMATION, FALSE, GetCurrentProcessId())); 
  SetPriorityClass(h.handle(), HIGH_PRIORITY_CLASS); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/2.2.1/main.cpp">Download source code</a></li></ul>
<p>The above example defines a class named <code class="classname">windows_handle</code> that calls the function <code class="function">CloseHandle()</code> in its destructor. Since it is a Windows API function, the program can only be executed on Windows. In Windows, many resources are required to be opened prior to their usage. This implicitly implies that resources should be closed once no longer used. The class <code class="classname">windows_handle</code> provides a mechanism to ensure just that.</p>
<p>An instance of type <code class="classname">windows_handle</code> is initialized with a handle. Windows utilizes handles in order to uniquely identify its resources. For example, the function <code class="function">OpenProcess()</code> returns a handle of type <code class="type">HANDLE</code> that can be used to access a currently running process. In the code example, the own process is accessed - in other words the application itself.</p>
<p>Using the returned handle, the process priority is increased allowing the application to request more CPU time from the scheduler. This is only for illustration purposes and does not serve any real benefit though. The important point here is that the resource opened with <code class="function">OpenProcess()</code> does not need to be explicitly closed using <code class="function">CloseHandle()</code>. Certainly, the resource is likely to be closed once the application terminates. However, in more complex applications the class <code class="classname">windows_handle</code> ensures that a resource is correctly closed if no longer needed. Once a particular resource leaves its visibility scope - in the above example of <var>h</var> at the end of the function <code class="function">main()</code> - the destructor is automatically invoked which in turn closes the contained resource.</p>
</div>
<hr>
<h2 class="title">
<a name="smartpointers_scoped_pointer"></a>2.3 Scoped Pointer</h2>
<div class="sect1">
<p>A scoped pointer is a pointer that is the sole owner of a dynamically allocated object. The corresponding class is named <code class="classname">boost::scoped_ptr</code> and is defined in <code class="filename">boost/scoped_ptr.hpp</code>. Unlike <code class="classname">std::auto_ptr</code>, a scoped pointer is not able to transfer ownership of its contained object to another scoped pointer. Once initialized with an address, the dynamically allocated object is released during destruction.</p>
<p>Since a scoped pointer simply stores and solely owns an address, the implementation of <code class="classname">boost::scoped_ptr</code> is less complex than <code class="classname">std::auto_ptr</code>. <code class="classname">boost::scoped_ptr</code> should be preferred if transfer of ownership is not required. In these situations, it may be a better choice than <code class="classname">std::auto_ptr</code> to avoid inadvertent transfer of ownership.</p>
<pre class="programlisting">#include &lt;boost/scoped_ptr.hpp&gt; 

int main() 
{ 
  boost::scoped_ptr&lt;int&gt; i(new int); 
  *i = 1; 
  *i.get() = 2; 
  i.reset(new int); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/2.3.1/main.cpp">Download source code</a></li></ul>
<p>Once initialized, the contained object of the smart pointer <code class="classname">boost::scoped_ptr</code> can be accessed through an interface similar to an ordinary pointer. This is achieved by providing the corresponding operator overloads <code class="methodname">operator*()</code>, <code class="methodname">operator-&gt;()</code> as well as <code class="methodname">operator bool()</code>. In addition, the methods <code class="methodname">get()</code> and <code class="methodname">reset()</code> are available. While the former one returns the address of the contained object, the latter one allows to reinitialize the smart pointer with a new object. In this case, the contained object is automatically destroyed before the new object is assigned.</p>
<p>The contained object is released using the <code class="code">delete</code> operator within the destructor of <code class="classname">boost::scoped_ptr</code>. This puts an important restriction on the types of objects <code class="classname">boost::scoped_ptr</code> can contain. <code class="classname">boost:scoped_ptr</code> is not allowed to be initialized with the address of a dynamically allocated array since this would require a call to the <code class="code">delete[]</code> operator instead. In these cases, the class <code class="classname">boost:scoped_array</code> can be used which is introduced next.</p>
</div>
<hr>
<h2 class="title">
<a name="smartpointers_scoped_array"></a>2.4 Scoped Array</h2>
<div class="sect1">
<p>A scoped array is used just like a scoped pointer. The crucial difference is that the destructor of the scoped array uses the <code class="code">delete[]</code> operator to release the contained object. Since this operator only applies to array objects, a scoped array must be initialized with the address of a dynamically allocated array.</p>
<p>The corresponding class for scoped arrays is <code class="classname">boost::scoped_array</code> and is defined in <code class="filename">boost/scoped_array.hpp</code>.</p>
<pre class="programlisting">#include &lt;boost/scoped_array.hpp&gt; 

int main() 
{ 
  boost::scoped_array&lt;int&gt; i(new int[2]); 
  *i.get() = 1; 
  i[1] = 2; 
  i.reset(new int[3]); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/2.4.1/main.cpp">Download source code</a></li></ul>
<p>The class <code class="classname">boost::scoped_array</code> provides overloads for the <code class="methodname">operator[]()</code> and <code class="methodname">operator bool()</code> operators. Using <code class="methodname">operator[]()</code>, a specific element of the array can be accessed - an object of type <code class="classname">boost::scoped_array</code> thus behaves exactly like the array it contains.</p>
<p>Just like <code class="classname">boost::scoped_ptr</code>, the methods <code class="methodname">get()</code> and <code class="methodname">reset()</code> are provided as well allowing to retrieve and reinitialize the address of the contained object.</p>
</div>
<hr>
<h2 class="title">
<a name="smartpointers_shared_pointer"></a>2.5 Shared Pointer</h2>
<div class="sect1">
<p>This smart pointer is one of the most utilized and has been badly missed in the first version of the C++ standard. It has been added to the standard as part of the Technical Report 1 (TR1). If this report is supported by the development environment used, the class <code class="classname">std::shared_ptr</code> defined in <code class="filename">memory</code> can be used. Within the Boost C++ library, this smart pointer is named <code class="classname">boost::shared_ptr</code> and is defined in <code class="filename">boost/shared_ptr.hpp</code>.</p>
<p>The smart pointer <code class="classname">boost::shared_ptr</code> is essentially similar to <code class="classname">boost::scoped_ptr</code>. The key difference is that <code class="classname">boost::shared_ptr</code> is not necessarily the exclusive owner of an object. The ownership can be shared with other smart pointers of type <code class="classname">boost::shared_ptr</code>. In these cases, the shared object is not released until the last shared pointer referencing the object is destroyed.</p>
<p>Since ownership can be shared with <code class="classname">boost::shared_ptr</code>, copies of any shared pointer can be created - opposed to <code class="classname">boost::scoped_ptr</code>. This actually allows the usage of smart pointers with the standard containers - something that cannot be done with <code class="classname">std::auto_ptr</code> since it transfers its ownership when copied.
    </p>
<pre class="programlisting">#include &lt;boost/shared_ptr.hpp&gt; 
#include &lt;vector&gt; 

int main() 
{ 
  std::vector&lt;boost::shared_ptr&lt;int&gt; &gt; v; 
  v.push_back(boost::shared_ptr&lt;int&gt;(new int(1))); 
  v.push_back(boost::shared_ptr&lt;int&gt;(new int(2))); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/2.5.1/main.cpp">Download source code</a></li></ul>
<p>Thanks to <code class="classname">boost::shared_ptr</code>, it is possible to safely use dynamically allocated objects with the standard containers as shown in the above example. Since <code class="classname">boost::shared_ptr</code> can share the ownership of its contained object, the copies stored by the container (as well as the additional copies in case the container needs to be rearranged) are equal. As outlined before, this is not the case with <code class="classname">std::auto_ptr</code> which therefore should never be stored within a container.</p>
<p>Similar to <code class="classname">boost::scoped_ptr</code>, the class <code class="classname">boost::shared_ptr</code> provides overloads for the following operators: <code class="methodname">operator*()</code>, <code class="methodname">operator-&gt;()</code> and <code class="methodname">operator bool()</code>. In addition, <code class="methodname">get()</code> and <code class="methodname">reset()</code> are available as well to retrieve and reinitialize the address of the contained object.</p>
<pre class="programlisting">#include &lt;boost/shared_ptr.hpp&gt; 

int main() 
{ 
  boost::shared_ptr&lt;int&gt; i1(new int(1)); 
  boost::shared_ptr&lt;int&gt; i2(i1); 
  i1.reset(new int(2)); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/2.5.2/main.cpp">Download source code</a></li></ul>
<p>The example defines two shared pointer <var>i1</var> and <var>i2</var> which both refer to the same object of type <code class="type">int</code>. While <var>i1</var> is explicitly initialized with the address returned by the <code class="code">new</code> operator, <var>i2</var> is copy-constructed of <var>i1</var>. The address of the contained integer of <var>i1</var> is then reinitialized by a call to <code class="methodname">reset()</code>. The previously contained object however is not released since it is still referenced by <var>i2</var>. The smart pointer <code class="classname">boost::shared_ptr</code> actually counts the number of shared pointers currently referencing the same object and releases it only once the last shared pointer loses its scope.</p>
<p>By default, <code class="classname">boost::shared_ptr</code> uses the <code class="code">delete</code> operator to destroy the contained object. However, the method of destruction can actually be specified as the following example illustrates:</p>
<pre class="programlisting">#include &lt;boost/shared_ptr.hpp&gt; 
#include &lt;windows.h&gt; 

int main() 
{ 
  boost::shared_ptr&lt;void&gt; h(OpenProcess(PROCESS_SET_INFORMATION, FALSE, GetCurrentProcessId()), CloseHandle); 
  SetPriorityClass(h.get(), HIGH_PRIORITY_CLASS); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/2.5.3/main.cpp">Download source code</a></li></ul>
<p>The constructor of <code class="classname">boost::shared_ptr</code> takes a regular function or a function object as the second parameter which in turn is used for destruction of the contained object. In the given example, the Windows API function <code class="function">CloseHandle()</code> is passed. Once the variable <var>h</var> loses its scope, the passed function is called instead of the <code class="code">delete</code> operator. In order to avoid compiler errors, the function is required to take one parameter of type <code class="type">HANDLE</code> which is the case with <code class="function">CloseHandle()</code>.</p>
<p>This example actually behaves the same as the one illustrating the RAII idiom earlier in this chapter. However, instead of defining a separate class <code class="classname">windows_handle</code>, the example takes advantage of the specific characteristics of <code class="classname">boost::shared_ptr</code> by passing a method to the constructor which is automatically called once the shared pointer loses its scope.</p>
</div>
<hr>
<h2 class="title">
<a name="smartpointers_shared_array"></a>2.6 Shared Array</h2>
<div class="sect1">
<p>A shared array works essentially the same as a shared pointer. The crucial difference is that the destructor of the shared array uses the <code class="code">delete[]</code> operator by default to release the contained object. Since this operator only applies to array objects, a shared array must be initialized with the address of a dynamically allocated array.</p>
<p>The corresponding class for shared arrays is <code class="classname">boost::shared_array</code> and is defined in <code class="filename">boost/shared_array.hpp</code>.</p>
<pre class="programlisting">#include &lt;boost/shared_array.hpp&gt; 
#include &lt;iostream&gt; 

int main() 
{ 
  boost::shared_array&lt;int&gt; i1(new int[2]); 
  boost::shared_array&lt;int&gt; i2(i1); 
  i1[0] = 1; 
  std::cout &lt;&lt; i2[0] &lt;&lt; std::endl; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/2.6.1/main.cpp">Download source code</a></li></ul>
<p>Just like with a shared pointer, the ownership of the contained object can be shared with other shared arrays. The example defines two variables <var>i1</var> and <var>i2</var> which both refer to the same dynamically allocated array. The value 1 - stored using the <code class="methodname">operator[]()</code> of <var>i1</var> - can be referenced and e.g. printed to the standard output stream using <var>i2</var>.</p>
<p>As with all the smart pointers introduced in this chapter, <code class="classname">boost::shared_array</code> also provides the methods <code class="methodname">get()</code> and <code class="methodname">reset()</code>. In addition, the <code class="methodname">operator bool()</code> is overloaded as well.</p>
</div>
<hr>
<h2 class="title">
<a name="smartpointers_weak_pointer"></a>2.7 Weak Pointer</h2>
<div class="sect1">
<p>Every smart pointer introduced so far can be used individually for different scenarios. In contrast, a weak pointer only makes sense if used in conjunction with a shared pointer. It is defined as <code class="classname">boost::weak_ptr</code> in <code class="filename">boost/weak_ptr.hpp</code></p>
<pre class="programlisting">#include &lt;windows.h&gt; 
#include &lt;boost/shared_ptr.hpp&gt; 
#include &lt;boost/weak_ptr.hpp&gt; 
#include &lt;iostream&gt; 

DWORD WINAPI reset(LPVOID p) 
{ 
  boost::shared_ptr&lt;int&gt; *sh = static_cast&lt;boost::shared_ptr&lt;int&gt;*&gt;(p); 
  sh-&gt;reset(); 
  return 0; 
} 

DWORD WINAPI print(LPVOID p) 
{ 
  boost::weak_ptr&lt;int&gt; *w = static_cast&lt;boost::weak_ptr&lt;int&gt;*&gt;(p); 
  boost::shared_ptr&lt;int&gt; sh = w-&gt;lock(); 
  if (sh) 
    std::cout &lt;&lt; *sh &lt;&lt; std::endl; 
  return 0; 
} 

int main() 
{ 
  boost::shared_ptr&lt;int&gt; sh(new int(99)); 
  boost::weak_ptr&lt;int&gt; w(sh); 
  HANDLE threads[2]; 
  threads[0] = CreateThread(0, 0, reset, &amp;sh, 0, 0); 
  threads[1] = CreateThread(0, 0, print, &amp;w, 0, 0); 
  WaitForMultipleObjects(2, threads, TRUE, INFINITE); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/2.7.1/main.cpp">Download source code</a></li></ul>
<p>A <code class="classname">boost::weak_ptr</code> must always be initialized with a <code class="classname">boost::shared_ptr</code>. Once initialized, it basically offers only one useful method: <code class="methodname">lock()</code>. It returns a <code class="classname">boost::shared_ptr</code> that shares ownership with the shared pointer used to initialize the weak pointer. In case the shared pointer does not contain any object, the returned one is empty as well.</p>
<p>Weak pointers make sense whenever a function is expected to work with an object managed by a shared pointer, but the lifetime of the object does not depend on the function itself. The function should only work with the object as long as it is owned by at least one shared pointer within the program. In case the shared pointer is reset, the object should not be kept alive due to an additional shared pointer inside the corresponding function.</p>
<p>The above example creates two threads inside <code class="function">main()</code> using functions provided by the Windows API. Thus, the example only compiles and executes under the Windows platform.</p>
<p>The first thread executes the function <code class="function">reset()</code> that receives the address of a shared pointer. The second thread executes the function <code class="function">print()</code> which contains the address of a weak pointer. This weak pointer has been previously initialized with the shared pointer.</p>
<p>Once the application is launched, both <code class="function">reset()</code> and <code class="function">print()</code> are executed at the same time. However, the order of execution cannot be predicted. This leads to the potential issue of <code class="function">reset()</code> destroying the object while it is being accessed by <code class="function">print()</code> at the same time.</p>
<p>The weak pointer solves this issue as follows: Invoking <code class="methodname">lock()</code> returns a shared pointer which points to a valid object in case it exists at the time of the call. If not, the shared pointer is set to 0 and thus equivalent to a standard null pointer.</p>
<p>The weak pointer itself does not have any impact on the lifetime of an object. In order to safely access the object within the <code class="function">print()</code> function nonetheless, <code class="methodname">lock()</code> returns a shared pointer. This guarantees that - even if the object is attempted to be released by a different thread - it continues to exist thanks to the returned shared pointer.</p>
</div>
<hr>
<h2 class="title">
<a name="smartpointers_intrusive_pointer"></a>2.8 Intrusive Pointer</h2>
<div class="sect1">
<p>In general, the intrusive pointer works exactly as the shared pointer. However, while <code class="classname">boost::shared_ptr</code> internally keeps track of the number of shared pointers referencing a particular object, the developer has to keep track of this information for the intrusive pointer. This is particularly helpful for e.g. framework objects that already keep track of the number of times they are referenced themselves.
    </p>
<p>The intrusive pointer is defined as <code class="classname">boost::intrusive_ptr</code> in <code class="filename">boost/intrusive_ptr.hpp</code>.</p>
<pre class="programlisting">#include &lt;boost/intrusive_ptr.hpp&gt; 
#include &lt;atlbase.h&gt; 
#include &lt;iostream&gt; 

void intrusive_ptr_add_ref(IDispatch *p) 
{ 
  p-&gt;AddRef(); 
} 

void intrusive_ptr_release(IDispatch *p) 
{ 
  p-&gt;Release(); 
} 

void check_windows_folder() 
{ 
  CLSID clsid; 
  CLSIDFromProgID(CComBSTR("Scripting.FileSystemObject"), &amp;clsid); 
  void *p; 
  CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER, __uuidof(IDispatch), &amp;p); 
  boost::intrusive_ptr&lt;IDispatch&gt; disp(static_cast&lt;IDispatch*&gt;(p)); 
  CComDispatchDriver dd(disp.get()); 
  CComVariant arg("C:\\Windows"); 
  CComVariant ret(false); 
  dd.Invoke1(CComBSTR("FolderExists"), &amp;arg, &amp;ret); 
  std::cout &lt;&lt; (ret.boolVal != 0) &lt;&lt; std::endl; 
} 

void main() 
{ 
  CoInitialize(0); 
  check_windows_folder(); 
  CoUninitialize(); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/2.8.1/main.cpp">Download source code</a></li></ul>
<p>The above example uses functions provided by COM (Component Object Model) thus, only builds and executes under the Windows platform. COM objects are a perfect example for <code class="classname">boost::intrusive_ptr</code> since they keep track of the number of pointers referencing them. The internal reference count can be incremented or decremented by 1 using the <code class="methodname">AddRef()</code> or <code class="methodname">Release()</code> method respectively. Once the counter reaches 0, the COM object is automatically destroyed.</p>
<p>The two methods <code class="methodname">AddRef()</code> and <code class="methodname">Release()</code> are called from within the <code class="function">intrusive_ptr_add_ref()</code> and <code class="function">intrusive_ptr_release()</code> functions to increment and decrement the internal reference counter of the corresponding COM object. The COM object used in this example is named 'FileSystemObject' and is available in Windows by default. It allows access to the underlying file system to e.g. verify whether or not a given directory exists. In the above example, the existence of a directory named <code class="filename">C:\Windows</code> is checked. How that works internally depends solely on COM and is irrelevant in regards to the functionality of <code class="classname">boost::intrusive_ptr</code>. The crucial point is that once the intrusive pointer <var>disp</var> loses its scope at the end of the <code class="function">check_windows_folder()</code> function, the function <code class="function">intrusive_ptr_release()</code> is going to be automatically called. This in turn will decrement the internal reference counter of the COM object 'FileSystemObject' to 0 and thus destroy the object.</p>
</div>
<hr>
<h2 class="title">
<a name="smartpointers_pointer_container"></a>2.9 Pointer Container</h2>
<div class="sect1">
<p>After meeting the different smart pointers of the Boost C++ Libraries, one should be able to write safe code for dynamically allocated objects as well as arrays. Many times, these objects are required to be stored within a container which - as seen above - is fairly easy using <code class="classname">boost::shared_ptr</code> and <code class="classname">boost::shared_array</code>.</p>
<pre class="programlisting">#include &lt;boost/shared_ptr.hpp&gt; 
#include &lt;vector&gt; 

int main() 
{ 
  std::vector&lt;boost::shared_ptr&lt;int&gt; &gt; v; 
  v.push_back(boost::shared_ptr&lt;int&gt;(new int(1))); 
  v.push_back(boost::shared_ptr&lt;int&gt;(new int(2))); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/2.9.1/main.cpp">Download source code</a></li></ul>
<p>While the code in the above example is absolutely correct and smart pointers can be used the given way, it is actually impractical for a couple of reasons. For once, the repetitive declaration of <code class="classname">boost::shared_ptr</code> requires more typing. In addition, copying the <code class="classname">boost::shared_ptr</code> to, from or within the container requires incrementing and decrementing the internal reference count constantly and thus is deemed very inefficient. For these reasons, the Boost C++ Libraries provide <a class="link" href="http://www.boost.org/libs/ptr_container/">Pointer Container</a> that are specialized for the management of dynamically allocated objects.</p>
<pre class="programlisting">#include &lt;boost/ptr_container/ptr_vector.hpp&gt; 

int main() 
{ 
  boost::ptr_vector&lt;int&gt; v; 
  v.push_back(new int(1)); 
  v.push_back(new int(2)); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/2.9.2/main.cpp">Download source code</a></li></ul>
<p>The class <code class="classname">boost::ptr_vector</code> defined in <code class="filename">boost/ptr_container/ptr_vector.hpp</code> works the same way as the container used and initialized with the <code class="classname">boost::shared_ptr</code> template parameter in the previous example. Since <code class="classname">boost::ptr_vector</code> is specialized for dynamically allocated objects, it is easier and more efficient to use though. However, as <code class="classname">boost::ptr_vector</code> is the solely owner of all contained objects, the ownership cannot be shared with a shared pointer not stored inside the container opposed to using <code class="code">std::vector&lt;boost::shared_ptr&lt;int&gt; &gt;</code>.</p>
<p>Besides <code class="classname">boost::ptr_vector</code>, additional containers specialized for managing dynamically allocated objects are available including <code class="classname">boost::ptr_deque</code>, <code class="classname">boost::ptr_list</code>, <code class="classname">boost::ptr_set</code>, <code class="classname">boost::ptr_map</code>, <code class="classname">boost::ptr_unordered_set</code> and <code class="classname">boost::ptr_unordered_map</code>.  These containers are equivalent to the ones provided by the C++ standard. The last two containers match the <code class="classname">std::unordered_set</code> and <code class="classname">std::unordered_map</code> containers added to the C++ standard as part of the Technical Report 1. They are also implemented as <code class="classname">boost::unordered_set</code> and <code class="classname">boost::unordered_map</code> by the Boost C++ Libraries that can be utilized if the used implementation of the C++ Standard does not support the Technical Report 1.</p>
</div>
<hr>
<h2 class="title">
<a name="smartpointers_exercises"></a>2.10 Exercises</h2>
<div class="sect1">
<p class="solution">
              You can buy 
              <a target="_top" href="http://en.highscore.de/shop/index.php?p=boost-solution">solutions to all exercises</a>
              in this book as a ZIP file. 
            </p>
<ol>
<li class="listitem">
<p>Optimize the following program by using an appropriate smart pointer:</p>
<pre class="programlisting">#include &lt;iostream&gt; 
#include &lt;cstring&gt; 

char *get(const char *s) 
{ 
  int size = std::strlen(s); 
  char *text = new char[size + 1]; 
  std::strncpy(text, s, size + 1); 
  return text; 
} 

void print(char *text) 
{ 
  std::cout &lt;&lt; text &lt;&lt; std::endl; 
} 

int main(int argc, char *argv[]) 
{ 
  if (argc &lt; 2) 
  { 
    std::cerr &lt;&lt; argv[0] &lt;&lt; " &lt;data&gt;" &lt;&lt; std::endl; 
    return 1; 
  } 

  char *text = get(argv[1]); 
  print(text); 
  delete[] text; 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/2.10.1/main.cpp">Download source code</a></li></ul>
</li>
<li class="listitem">
<p>Optimize the following program:</p>
<pre class="programlisting">#include &lt;vector&gt; 

template &lt;typename T&gt; 
T *create() 
{ 
  return new T; 
} 

int main() 
{ 
  std::vector&lt;int*&gt; v; 
  v.push_back(create&lt;int&gt;()); 
} </pre>
<ul class="programlisting"><li><a class="programlisting" href="src/2.10.2/main.cpp">Download source code</a></li></ul>
</li>
</ol>
</div>
</div>
<hr class="hrfoot">
<p class="copyright">Copyright © 2008-2010 
        <a class="link" href="mailto:boris@highscore.de">Boris Schäling</a>
      </p>
</body>
</html>
